using System.Xml.Serialization;
using System.Xml.Schema;
using System.Xml;
using System.Collections.Generic;
using System;
using Xyne.Objects;
using Xyne.Actions;

namespace Xyne.CardManagement
{
    public class CardData : IXmlSerializable
    {
        public const int PatternSize = 4;

        private long id;
        public long Id
        {
            get { return id; }
            set { id = value; }
        }

        private String name;
        public String Name
        {
            get { return name; }
            set { name = value; }
        }

        private String description;
        public String Description
        {
            get { return description; }
            set { description = value; }
        }

        private String icon;
        public String Icon
        {
            get
            {
                return icon;
            }

            set
            {
                icon = value;
            }
        }

        private List<AlignmentEnum> alignments = new List<AlignmentEnum>();
        public List<AlignmentEnum> Alignments
        {
            get { return alignments; }
            set { alignments = value; }
        }

        private PatternValue[,] pattern;
        public PatternValue[,] Pattern
        {
            get { return pattern; }
            set { pattern = value; }
        }

        private List<Action> actions = new List<Action>();
        public List<Action> Actions
        {
            get { return actions; }
        }

        public int NumPieces
        {
            get
            {
                int colorCount = 0;
                foreach (PatternValue color in pattern)
                {
                    if (color.Value != PatternValueEnum.None)
                    {
                        colorCount++;
                    }
                }
                return colorCount;
            }
        }

        public CardData()
        {
        }

        public CardData(CardData data)
        {
            Id = data.Id;
            Name = data.Name;
            Description = data.Description;
            Icon = data.Icon;
            alignments = new List<AlignmentEnum>(data.Alignments);
            pattern = new PatternValue[data.Pattern.GetLength(0), data.Pattern.GetLength(1)];
            for (int x = 0; x < data.Pattern.GetLength(0); x++)
                for (int y = 0; y < data.Pattern.GetLength(1); y++)
                    pattern[x, y] = data.Pattern[x, y];

            foreach (Action action in data.Actions)
            {
                Action copy = Action.GetCopy(action);
                if (copy != null)
                    Actions.Add(copy);
            }
        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteAttributeString("Id", id.ToString());
            writer.WriteAttributeString("Name", name);
            writer.WriteAttributeString("Description", description);
            writer.WriteAttributeString("Icon", icon);
            writer.WriteStartElement("Alignments");
            foreach (AlignmentEnum alignment in alignments)
            {
                writer.WriteElementString("Alignment", alignment.ToString());
            }
            writer.WriteEndElement();

            if (pattern != null)
            {
                writer.WriteStartElement("Pattern");
                for (int y = 0; y < pattern.GetLength(0); y++)
                {
                    String s = String.Empty;
                    for (int x = 0; x < pattern.GetLength(1); x++)
                    {
                        s += pattern[x, y].ToString();
                    }
                    writer.WriteElementString("p", s);
                }
                writer.WriteEndElement();
            }
            writer.WriteStartElement("Actions");
            foreach (Action action in Actions)
            {
                writer.WriteStartElement("Action");
                action.WriteXml(writer);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        public void ReadXml(XmlReader reader)
        {
            String myName = reader.LocalName;

            id = long.Parse(reader.GetAttribute("Id"));
            name = reader.GetAttribute("Name");
            description = reader.GetAttribute("Description");
            icon = reader.GetAttribute("Icon");
            while (reader.Read() && reader.LocalName != myName)
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.LocalName == "Alignments")
                    {
                        while (reader.Read() && reader.LocalName != "Alignments")
                        {
                            if (reader.NodeType == XmlNodeType.Element && reader.LocalName == "Alignment")
                            {
                                alignments.Add((AlignmentEnum)Enum.Parse(typeof(AlignmentEnum), reader.ReadString(),true));
                            }
                        }
                    }
                    if (reader.LocalName == "Pattern")
                    {
                        PatternValue[,] pattern = new PatternValue[4, 4];
                        int pos = 0;
                        while (reader.Read() && reader.LocalName != "Pattern")
                        {
                            if (pos < PatternSize && reader.NodeType == XmlNodeType.Element && reader.LocalName == "p")
                            {
                                String line = reader.ReadString();
                                if (line.Length == PatternSize)
                                {
                                    for (int i = 0; i < PatternSize; i++)
                                        pattern[i, pos] = PatternValue.Parse(line[i]);

                                    pos++;
                                }
                            }
                        }
                        if (pos == PatternSize)
                            this.pattern = pattern;
                    }
                    else if (reader.LocalName == "Actions")
                    {
                        while (reader.Read() && reader.LocalName != "Actions")
                        {
                            if (reader.NodeType == XmlNodeType.Element && reader.LocalName == "Action")
                            {
                                Action action = Action.ReadActionFromXml(reader);
                                if (action != null)
                                    actions.Add(action);
                            }
                        }
                    }
                }
            }

            reader.ReadEndElement();
        }

        public XmlSchema GetSchema()
        {
            return null;
        }
    }
}
